头部背景图片
360 儿童卫士云团队 |
360 儿童卫士云团队 |

Web 常见问题排查

分享一些平时经典查错手段,人生苦短,我们的目标是,电话通知出bug后,秒登vpn,千里之外定位问题,瞬息之间修复上线,今天不加班

Nginx 日常排查

根据不同问题,要选择合适的方法,最简单的方法还是查看 error_log,有些怪异的问题,从error_log中中能找到蛛丝马迹。慢请求相关的问题,可通过access_log记录请求时间。如果log中没有什么有用信息,可以尝试分析下系统调用,或网络。程序本身的问题,可能需要gdb调试。

0x01 检查 error_log

error_log 提供了异常丰富的信息,比如nginx处理请求出错,网络连接出错,后端返回出错,系统调用出错等各种错误信息,如果是线下调试,则可以开启debug信息,便于调试排查

  • connect,write,read timeout 等网络超时错误
  • Permission deniedFile not found等系统调用错误
  • HTTP状态码400,499,500等对应的错误
HTTP 503

503 Service Temporarily Unavailable

故障检测: 先定位到前端故障服务器节点,在前端服务器上ping后端服务器查看网络延迟丢包情况,后端服务端口响应时间。如发现延迟>100ms,丢包>5%。说明前端到后端网络出现问题。HTTP 503 Service Temporarily Unavailable 故障一般是前端访问后端网络延迟导致。首选排查是不是后端流量过载导致。如果不是,就是前端到后端网络问题。

HTTP 504

504 Gateway Time-out

故障检测: 查看后端服务器Nginx php mysql资源占用情况,并查看相关错误日志。此类故障几率比较小HTTP 504 Gateway Time-out 故障一般是因的后端服务器响应超时。如PHP程序执行时间太长,数据库查询超时。与程序沟通是否需要增加PHP 执行超时时间。

0x02 检查 access_log

access_log 提供了客户端访问日志,nginx 的access_log可灵活定义日志格式,日志内容,比如后端响应时间,后端返回状态码,后端的failover过程等,另外,也可根据access_log 进行统计,比如根据接口统计,根据客户端IP统计,根据服务端IP统计,根据后端响应时间统计等。

  • 统计HTTP状态码比例,从而知道nginx服务状况
  • 统计响应时间,判断超时请求
  • 根据经验,如果响应时间分布集中在某个数字,并且标准差很小,则很可能是因为超时。
  • 统计QPS, 对比负载是否均衡

Nginx做反向代理,有时发现某些接口较慢,通常在3s左右

  • nginx access_log 可以记录 upstream_response_time
  • 分析access_logupstream_response_time,发现响应大约3s
  • 分析后端 access_log,处理时间在毫秒级别
  • 最终发现,问题是由于nginx跟后端connect较慢导致

truss、strace或ltrace查看系统调用

strace和truss用来 用来跟踪系统调用,并可以打印丰富的信息,比如系统调用发生的时间,调用耗时,传参的内容,调用返回结果等等。

truss是早期为System V R4开发的调试程序,包括Aix、FreeBSD在内的大部分Unix系统都自带了这个工具;而strace最初是为SunOS系统编写的,这两个工具现在也已被移植到了大部分Unix系统中,大多数Linux发行版都自带了strace和ltrace,
ltrace用来 跟踪进程调用库函数的情况,ltrace最早出现在GNU/Debian Linux中。

1
2
3
-f :除了跟踪当前进程外,还跟踪其子进程。
-o file :将输出信息写到文件file中,而不是显示到标准错误输出(stderr)。
-p pid :绑定到一个由pid对应的正在运行的进程。此参数常用来调试后台进程。

使用上述三个参数基本上就可以完成大多数调试任务了,下面举几个命令行例子:

1
2
truss -o ls.truss ls -al: 跟踪ls -al的运行,将输出信息写到文件/tmp/ls.truss中。
strace -f -o vim.strace vim: 跟踪vim及其子进程的运行,将输出信息写到文件vim.strace。

另一个十分有用的功能参数-c:

1
2
3
4
5
6
7
8
// 各项含义如下:

- % time:执行耗时占总时间百分比
- seconds:执行总时间
- usecs/call:单个命令执行时间
- calls:调用次数
- errors: 出错次数
- syscall: 系统调用
案例一 futex 表示很可能发生了死锁
1
2
3
4
[pushaowei@kidsguard ~]$ sudo strace -p 1477

Process 1477 attached - interrupt to quit
futex(0x398ad53594, FUTEX_WAIT_PRIVATE, 2, NULL
案例二 处理PHP请求过慢

可以用strace来验证系统调用耗时,在一次排查PHP问题时,发现有时PHP处理请求过慢,strace –T 发现是flock 调用过慢。

1
2
3
1516867165.279482 flock(4, LOCK_EX)     = 0  < 0.389046 >
1516867165.668528 write(4, "1\t1\t1403674085\t11"..., 76) = 76 <0 .000037 >
1516867165.668565 flock(4, LOCK_UN) = 0 <<0.000017>


综合分析

web服务器访问慢通常是以下几类问题:

  1. 系统资源不足检查服务器CPU/内存/IO/带宽是否成为瓶颈,异常情况也不要放过,比如CPU单核占用过高,内存时高时低等
  2. 内核、程序参数设置不合理看看有没有报内核错误,连接数用户打开文件数这些有没有达到上限等等
  3. 链路本身慢是否跨运营商、用户上下行带宽不够、dns解析慢、服务器内网广播风暴什么的
  4. 程序设计不合理是否程序本身算法设计太差,数据库语句太过复杂
  5. 其它关联的程序引起的如果要访问数据库,检查一下是否数据库访问慢
  6. 是否被攻击了查看服务器是否被DDOS了等等
  7. 硬件故障这个一般直接服务器就挂了,而不是访问慢某些故障会伴随一些其它现象发生,比如说CPU过高/内存过高/网络带宽被打满/nf_contrack表设置过低的时候你会发现SSH上去敲命令都很慢。排查思路没有固定的套路,不过某些经验和知识能够加快你的定位问题的速度,应该先把能想到的都加上监控项,然后结合报警、经验利用控制变量法具体分析。